//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using Tathata.Common.Caching;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Data;
using System.Globalization;
using Tathata.Common.DAL;
using System.Security.Cryptography;
using Tathata.Common.Utils;
using System.Web.Security;
using Tathata.Common.BLL.Entities;
using Tathata.Common.Localization;
using Tathata.Common.BLL.EntityCollections;

namespace Tathata.Common.DAL.Managers
{
    /// <summary>
    /// Customer database manager
    /// </summary>
    internal class CustomerDBManager
    {
        #region Methods

        /// <summary>
        /// Gets all customers
        /// </summary>
        /// <returns>Customer collection</returns>
        public static CustomerCollection GetAllCustomers()
        {
            CustomerCollection customerCollection = new CustomerCollection();
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerLoadAll");
            using (IDataReader dataReader = db.ExecuteReader(dbCommand))
            {
                while (dataReader.Read())
                {
                    Customer customer = new Customer();
                    customer.CustomerID = NopDataHelper.GetInt(dataReader, "CustomerID");
                    customer.CustomerGUID = NopDataHelper.GetGuid(dataReader, "CustomerGUID");
                    customer.Email = NopDataHelper.GetString(dataReader, "Email");
                    customer.PasswordHash = NopDataHelper.GetString(dataReader, "PasswordHash");
                    customer.SaltKey = NopDataHelper.GetString(dataReader, "SaltKey");
                    customer.AffiliateID = NopDataHelper.GetInt(dataReader, "AffiliateID");
                    customer.LanguageID = NopDataHelper.GetInt(dataReader, "LanguageID");
                    customer.CurrencyID = NopDataHelper.GetInt(dataReader, "CurrencyID");
                    customer.IsAdmin = NopDataHelper.GetBoolean(dataReader, "IsAdmin");
                    customer.Active = NopDataHelper.GetBoolean(dataReader, "Active");
                    customer.Deleted = NopDataHelper.GetBoolean(dataReader, "Deleted");
                    customer.RegistrationDate = NopDataHelper.GetDateTime(dataReader, "RegistrationDate");
                    customerCollection.Add(customer);
                }
            }

            return customerCollection;
        }
        
        /// <summary>
        /// Gets all customers by affiliate identifier
        /// </summary>
        /// <param name="AffiliateID">Affiliate identifier</param>
        /// <returns>Customer collection</returns>
        public static CustomerCollection GetByAffiliateID(int AffiliateID)
        {
            CustomerCollection customerCollection = new CustomerCollection();
            if (AffiliateID == 0)
                return customerCollection;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerLoadByAffiliateID");
            db.AddInParameter(dbCommand, "AffiliateID", DbType.Int32, AffiliateID);
            using (IDataReader dataReader = db.ExecuteReader(dbCommand))
            {
                while (dataReader.Read())
                {
                    Customer customer = new Customer();
                    customer.CustomerID = NopDataHelper.GetInt(dataReader, "CustomerID");
                    customer.CustomerGUID = NopDataHelper.GetGuid(dataReader, "CustomerGUID");
                    customer.Email = NopDataHelper.GetString(dataReader, "Email");
                    customer.PasswordHash = NopDataHelper.GetString(dataReader, "PasswordHash");
                    customer.SaltKey = NopDataHelper.GetString(dataReader, "SaltKey");
                    customer.AffiliateID = NopDataHelper.GetInt(dataReader, "AffiliateID");
                    customer.LanguageID = NopDataHelper.GetInt(dataReader, "LanguageID");
                    customer.CurrencyID = NopDataHelper.GetInt(dataReader, "CurrencyID");
                    customer.IsAdmin = NopDataHelper.GetBoolean(dataReader, "IsAdmin");
                    customer.Active = NopDataHelper.GetBoolean(dataReader, "Active");
                    customer.Deleted = NopDataHelper.GetBoolean(dataReader, "Deleted");
                    customer.RegistrationDate = NopDataHelper.GetDateTime(dataReader, "RegistrationDate");
                    customerCollection.Add(customer);
                }
            }

            return customerCollection;
        }

        /// <summary>
        /// Gets all customers by customer role id
        /// </summary>
        /// <param name="CustomerRoleID">Customer role identifier</param>
        /// <param name="showHidden">A value indicating whether to show hidden records</param>
        /// <returns>Customer collection</returns>
        public static CustomerCollection GetByCustomerRoleID(int CustomerRoleID, bool showHidden)
        {
            CustomerCollection customerCollection = new CustomerCollection();
            if (CustomerRoleID == 0)
                return customerCollection;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerLoadByCustomerRoleID");
            db.AddInParameter(dbCommand, "ShowHidden", DbType.Boolean, showHidden);
            db.AddInParameter(dbCommand, "CustomerRoleID", DbType.Int32, CustomerRoleID);
            using (IDataReader dataReader = db.ExecuteReader(dbCommand))
            {
                while (dataReader.Read())
                {
                    Customer customer = new Customer();
                    customer.CustomerID = NopDataHelper.GetInt(dataReader, "CustomerID");
                    customer.CustomerGUID = NopDataHelper.GetGuid(dataReader, "CustomerGUID");
                    customer.Email = NopDataHelper.GetString(dataReader, "Email");
                    customer.PasswordHash = NopDataHelper.GetString(dataReader, "PasswordHash");
                    customer.SaltKey = NopDataHelper.GetString(dataReader, "SaltKey");
                    customer.AffiliateID = NopDataHelper.GetInt(dataReader, "AffiliateID");
                    customer.LanguageID = NopDataHelper.GetInt(dataReader, "LanguageID");
                    customer.CurrencyID = NopDataHelper.GetInt(dataReader, "CurrencyID");
                    customer.IsAdmin = NopDataHelper.GetBoolean(dataReader, "IsAdmin");
                    customer.Active = NopDataHelper.GetBoolean(dataReader, "Active");
                    customer.Deleted = NopDataHelper.GetBoolean(dataReader, "Deleted");
                    customer.RegistrationDate = NopDataHelper.GetDateTime(dataReader, "RegistrationDate");
                    customerCollection.Add(customer);
                }
            }

            return customerCollection;
        }

        /// <summary>
        /// Gets a customer by email
        /// </summary>
        /// <param name="Email">Customer Email</param>
        /// <returns>A customer</returns>
        public static Customer GetByEmail(string Email)
        {
            Customer customer = null;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerLoadByEmail");
            db.AddInParameter(dbCommand, "Email", DbType.String, Email);
            using (IDataReader dataReader = db.ExecuteReader(dbCommand))
            {
                while (dataReader.Read())
                {
                    customer = new Customer();
                    customer.CustomerID = NopDataHelper.GetInt(dataReader, "CustomerID");
                    customer.CustomerGUID = NopDataHelper.GetGuid(dataReader, "CustomerGUID");
                    customer.Email = NopDataHelper.GetString(dataReader, "Email");
                    customer.PasswordHash = NopDataHelper.GetString(dataReader, "PasswordHash");
                    customer.SaltKey = NopDataHelper.GetString(dataReader, "SaltKey");
                    customer.AffiliateID = NopDataHelper.GetInt(dataReader, "AffiliateID");
                    customer.LanguageID = NopDataHelper.GetInt(dataReader, "LanguageID");
                    customer.CurrencyID = NopDataHelper.GetInt(dataReader, "CurrencyID");
                    customer.IsAdmin = NopDataHelper.GetBoolean(dataReader, "IsAdmin");
                    customer.Active = NopDataHelper.GetBoolean(dataReader, "Active");
                    customer.Deleted = NopDataHelper.GetBoolean(dataReader, "Deleted");
                    customer.RegistrationDate = NopDataHelper.GetDateTime(dataReader, "RegistrationDate");

                }
            }

            return customer;
        }

        /// <summary>
        /// Gets a customer
        /// </summary>
        /// <param name="CustomerID">Customer identifier</param>
        /// <returns>A customer</returns>
        public static Customer GetByCustomerID(int CustomerID)
        {
            Customer customer = null;
            if (CustomerID == 0)
                return customer;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerLoadByPrimaryKey");
            db.AddInParameter(dbCommand, "CustomerID", DbType.Int32, CustomerID);
            using (IDataReader dataReader = db.ExecuteReader(dbCommand))
            {
                if (dataReader.Read())
                {
                    customer = new Customer();
                    customer.CustomerID = NopDataHelper.GetInt(dataReader, "CustomerID");
                    customer.CustomerGUID = NopDataHelper.GetGuid(dataReader, "CustomerGUID");
                    customer.Email = NopDataHelper.GetString(dataReader, "Email");
                    customer.PasswordHash = NopDataHelper.GetString(dataReader, "PasswordHash");
                    customer.SaltKey = NopDataHelper.GetString(dataReader, "SaltKey");
                    customer.AffiliateID = NopDataHelper.GetInt(dataReader, "AffiliateID");
                    customer.LanguageID = NopDataHelper.GetInt(dataReader, "LanguageID");
                    customer.CurrencyID = NopDataHelper.GetInt(dataReader, "CurrencyID");
                    customer.IsAdmin = NopDataHelper.GetBoolean(dataReader, "IsAdmin");
                    customer.Active = NopDataHelper.GetBoolean(dataReader, "Active");
                    customer.Deleted = NopDataHelper.GetBoolean(dataReader, "Deleted");
                    customer.RegistrationDate = NopDataHelper.GetDateTime(dataReader, "RegistrationDate");
                }
            }

            return customer;
        }

        /// <summary>
        /// Gets a customer by GUID
        /// </summary>
        /// <param name="CustomerGUID">Customer GUID</param>
        /// <returns>A customer</returns>
        public static Customer GetByCustomerGUID(Guid CustomerGUID)
        {
            Customer customer = null;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerLoadByGUID");
            db.AddInParameter(dbCommand, "CustomerGUID", DbType.Guid, CustomerGUID);
            using (IDataReader dataReader = db.ExecuteReader(dbCommand))
            {
                if (dataReader.Read())
                {
                    customer = new Customer();
                    customer.CustomerID = NopDataHelper.GetInt(dataReader, "CustomerID");
                    customer.CustomerGUID = NopDataHelper.GetGuid(dataReader, "CustomerGUID");
                    customer.Email = NopDataHelper.GetString(dataReader, "Email");
                    customer.PasswordHash = NopDataHelper.GetString(dataReader, "PasswordHash");
                    customer.SaltKey = NopDataHelper.GetString(dataReader, "SaltKey");
                    customer.AffiliateID = NopDataHelper.GetInt(dataReader, "AffiliateID");
                    customer.LanguageID = NopDataHelper.GetInt(dataReader, "LanguageID");
                    customer.CurrencyID = NopDataHelper.GetInt(dataReader, "CurrencyID");
                    customer.IsAdmin = NopDataHelper.GetBoolean(dataReader, "IsAdmin");
                    customer.Active = NopDataHelper.GetBoolean(dataReader, "Active");
                    customer.Deleted = NopDataHelper.GetBoolean(dataReader, "Deleted");
                    customer.RegistrationDate = NopDataHelper.GetDateTime(dataReader, "RegistrationDate");
                }
            }

            return customer;
        }

        /// <summary>
        /// Adds a customer
        /// </summary>
        /// <param name="CustomerGUID">The customer identifier</param>
        /// <param name="Email">The email</param>
        /// <param name="passwordHash">The password hash</param>
        /// <param name="saltKey">The salt key</param>
        /// <param name="AffiliateID">The affiliate identifier</param>
        /// <param name="LanguageID">The language identifier</param>
        /// <param name="CurrencyID">The currency identifier</param>
        /// <param name="IsAdmin">A value indicating whether the customer is administrator</param>
        /// <param name="Active">A value indicating whether the customer is active</param>
        /// <param name="Deleted">A value indicating whether the customer has been deleted</param>
        /// <param name="RegistrationDate">The date and time of customer registration</param>
        /// <returns>A customer</returns>
        public static Customer AddCustomer(Guid CustomerGUID, string Email,
            string passwordHash, string saltKey,
            int AffiliateID,
             int LanguageID, int CurrencyID,
            bool IsAdmin, bool Active, bool Deleted, DateTime RegistrationDate)
        {
            Customer customer = null;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerInsert");
            db.AddOutParameter(dbCommand, "CustomerID", DbType.Int32, 0);
            db.AddInParameter(dbCommand, "CustomerGUID", DbType.Guid, CustomerGUID);
            db.AddInParameter(dbCommand, "Email", DbType.String, Email);
            db.AddInParameter(dbCommand, "PasswordHash", DbType.String, passwordHash);
            db.AddInParameter(dbCommand, "SaltKey", DbType.String, saltKey);
            db.AddInParameter(dbCommand, "AffiliateID", DbType.Int32, AffiliateID);
            db.AddInParameter(dbCommand, "LanguageID", DbType.Int32, LanguageID);
            db.AddInParameter(dbCommand, "CurrencyID", DbType.Int32, CurrencyID);
            db.AddInParameter(dbCommand, "IsAdmin", DbType.Boolean, IsAdmin);
            db.AddInParameter(dbCommand, "Active", DbType.Boolean, Active);
            db.AddInParameter(dbCommand, "Deleted", DbType.Boolean, Deleted);
            db.AddInParameter(dbCommand, "RegistrationDate", DbType.DateTime, RegistrationDate);

            if (db.ExecuteNonQuery(dbCommand) > 0)
            {
                int CustomerID = Convert.ToInt32(db.GetParameterValue(dbCommand, "@CustomerID"));
                customer = GetByCustomerID(CustomerID);
            }

            return customer;
        }

        /// <summary>
        /// Updates the customer
        /// </summary>
        /// <param name="CustomerID">The customer identifier</param>
        /// <param name="CustomerGUID">The customer identifier</param>
        /// <param name="Email">The email</param>
        /// <param name="PasswordHash">The password hash</param>
        /// <param name="SaltKey">The salk key</param>
        /// <param name="AffiliateID">The affiliate identifier</param>
        /// <param name="LanguageID">The language identifier</param>
        /// <param name="CurrencyID">The currency identifier</param>
        /// <param name="IsAdmin">A value indicating whether the customer is administrator</param>
        /// <param name="Active">A value indicating whether the customer is active</param>
        /// <param name="Deleted">A value indicating whether the customer has been deleted</param>
        /// <param name="RegistrationDate">The date and time of customer registration</param>
        /// <returns>A customer</returns>
        public static Customer UpdateCustomer(int CustomerID, Guid CustomerGUID, string Email,
            string PasswordHash, string SaltKey, int AffiliateID,
             int LanguageID,
            int CurrencyID, bool IsAdmin, bool Active, bool Deleted, DateTime RegistrationDate)
        {
            Customer customer = null;
            Database db = NopDataHelper.CreateConnection();
            DbCommand dbCommand = db.GetStoredProcCommand("Nop_CustomerUpdate");
            db.AddInParameter(dbCommand, "CustomerID", DbType.Int32, CustomerID);
            db.AddInParameter(dbCommand, "CustomerGUID", DbType.Guid, CustomerGUID);
            db.AddInParameter(dbCommand, "Email", DbType.String, Email);
            db.AddInParameter(dbCommand, "PasswordHash", DbType.String, PasswordHash);
            db.AddInParameter(dbCommand, "SaltKey", DbType.String, SaltKey);
            db.AddInParameter(dbCommand, "AffiliateID", DbType.Int32, AffiliateID);
            db.AddInParameter(dbCommand, "LanguageID", DbType.Int32, LanguageID);
            db.AddInParameter(dbCommand, "CurrencyID", DbType.Int32, CurrencyID);
            db.AddInParameter(dbCommand, "IsAdmin", DbType.Boolean, IsAdmin);
            db.AddInParameter(dbCommand, "Active", DbType.Boolean, Active);
            db.AddInParameter(dbCommand, "Deleted", DbType.Boolean, Deleted);
            db.AddInParameter(dbCommand, "RegistrationDate", DbType.DateTime, RegistrationDate);

            if (db.ExecuteNonQuery(dbCommand) > 0)
            {
                customer = GetByCustomerID(CustomerID);
            }

            return customer;
        }
        #endregion
    }
}
